home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 001 / pibt3sp3.arc / PIBSCREN.PAS < prev    next >
Pascal/Delphi Source File  |  1985-08-22  |  40KB  |  806 lines

  1. (*----------------------------------------------------------------------*)
  2. (*       PIBSCREN.PAS --- Screen Handling Routines for Turbo Pascal     *)
  3. (*----------------------------------------------------------------------*)
  4. (*                                                                      *)
  5. (*  Author:  Philip R. Burns                                            *)
  6. (*                                                                      *)
  7. (*  Date:    Version 1.0: January, 1985 (Part of PibMenus)              *)
  8. (*           Version 1.1: March, 1985   (Part of PibMenus)              *)
  9. (*           Version 1.2: May, 1985     (Part of PibMenus)              *)
  10. (*           Version 2.0: June, 1985    (Split from PibMenus)           *)
  11. (*                                                                      *)
  12. (*  Systems: For MS-DOS on IBM PCs and close compatibles only.          *)
  13. (*           Note:  I have checked these on Zenith 151s under           *)
  14. (*                  MSDOS 2.1 and IBM PCs under PCDOS 2.0.              *)
  15. (*                                                                      *)
  16. (*  History: These routines provide a simple windowing facility for     *)
  17. (*           Turbo Pascal as well as routines for direct access to the  *)
  18. (*           screen memory area.                                        *)
  19. (*                                                                      *)
  20. (*           The windowing facility provides windows similar to those   *)
  21. (*           implemented in QMODEM by John Friel III.                   *)
  22. (*                                                                      *)
  23. (*           Version 1.0 of these routines formed part of the           *)
  24. (*           PIBMENUS.PAS include file.  These routines were split off  *)
  25. (*           into a separate PIBSCREN.PAS file at version 2.0.          *)
  26. (*                                                                      *)
  27. (*           Thanks to Mike Harrington for an elegant way of finding    *)
  28. (*           the current upper left corner of a window without using    *)
  29. (*           the kludge implemented in version 1.1.                     *)
  30. (*                                                                      *)
  31. (*           Suggestions for improvements or corrections are welcome.   *)
  32. (*           Please leave messages on Gene Plantz's BBS (312) 882 4145  *)
  33. (*           or Ron Fox's BBS (312) 940 6496.                           *)
  34. (*                                                                      *)
  35. (*           If you use this code in your own programs, please be nice  *)
  36. (*           and give all of us credit.                                 *)
  37. (*                                                                      *)
  38. (*----------------------------------------------------------------------*)
  39. (*                                                                      *)
  40. (*  Needs:  These routines need the include files MINMAX.PAS,           *)
  41. (*          GLOBTYPE.PAS, ASCII.PAS, and INT24.PAS. These files are not *)
  42. (*          included here, since Turbo regrettably does not allow       *)
  43. (*          nested includes.                                            *)
  44. (*                                                                      *)
  45. (*----------------------------------------------------------------------*)
  46. (*                                                                      *)
  47. (*    Note that code for stacked windows is available here.  You may    *)
  48. (*    want to modify this to use compile-time window spaces, or remove  *)
  49. (*    the current push-down stack structure.                            *)
  50. (*                                                                      *)
  51. (*----------------------------------------------------------------------*)
  52.  
  53. (*----------------------------------------------------------------------*)
  54. (*           Constants, Types, and Variables for Screen Access          *)
  55. (*----------------------------------------------------------------------*)
  56.  
  57. CONST
  58.    Color_Screen_Address   = $B800;   (* Address of color screen          *)
  59.    Mono_Screen_Address    = $B000;   (* Address of mono screen           *)
  60.    Screen_Length          = 4000;    (* 80 x 25 x 2 = screen area length *)
  61.    Max_Saved_Screen       = 5;       (* Maximum no. of saved screens     *)
  62.  
  63. TYPE
  64.                                      (* A screen image            *)
  65.  
  66.    Screen_Type       = ARRAY[ 1 .. Screen_Length ] OF BYTE;
  67.  
  68.    Screen_Ptr        = ^Screen_Image_Type;
  69.  
  70.    Screen_Image_Type = RECORD
  71.                           Screen_Image: Screen_Type;
  72.                        END;
  73.  
  74.                                               (* Screen stack entries      *)
  75.    Saved_Screen_Ptr  = ^Saved_Screen_Type;
  76.  
  77.    Saved_Screen_Type = RECORD
  78.                           Screen_Image  : Screen_Type;
  79.                           Screen_Row    : INTEGER;
  80.                           Screen_Column : INTEGER;
  81.                           Screen_X1     : INTEGER;
  82.                           Screen_Y1     : INTEGER;
  83.                           Screen_X2     : INTEGER;
  84.                           Screen_Y2     : INTEGER;
  85.                        END;
  86.  
  87. VAR
  88.                                               (* Memory-mapped screen area *)
  89.    Actual_Screen        : Screen_Ptr;
  90.                                               (* Saves screen behind menus *)
  91.  
  92.    Saved_Screen         : Saved_Screen_Ptr;
  93.  
  94.                                               (* Stack of saved screens    *)
  95.  
  96.    Saved_Screen_List    : ARRAY[ 1 .. Max_Saved_Screen ] OF Saved_Screen_Ptr;
  97.  
  98. (* STRUCTURED *) CONST
  99.                                               (* Depth of saved screen stack *)
  100.    Current_Saved_Screen : 0 .. Max_Saved_Screen = 0;
  101.  
  102. (*----------------------------------------------------------------------*)
  103. (*    Color_Screen_Active --- Determine if color or mono screen         *)
  104. (*----------------------------------------------------------------------*)
  105.  
  106. FUNCTION Color_Screen_Active : BOOLEAN;
  107.  
  108. (*----------------------------------------------------------------------*)
  109. (*                                                                      *)
  110. (*     Function:   Color_Screen_Active                                  *)
  111. (*                                                                      *)
  112. (*     Purpose:    Determines if color or mono screen active            *)
  113. (*                                                                      *)
  114. (*     Calling Sequence:                                                *)
  115. (*                                                                      *)
  116. (*        Color_Active := Color_Screen_Active : BOOLEAN;                *)
  117. (*                                                                      *)
  118. (*           Color_Active --- set to TRUE if the color screen is        *)
  119. (*                            active, FALSE if the mono screen is       *)
  120. (*                            active.                                   *)
  121. (*                                                                      *)
  122. (*     Calls:   INTR                                                    *)
  123. (*                                                                      *)
  124. (*----------------------------------------------------------------------*)
  125.  
  126. VAR
  127.    Regs : RegPack;
  128.  
  129. BEGIN  (* Color_Screen_Active *)
  130.  
  131.    Regs.Ax := 15 SHL 8;
  132.  
  133.    INTR( $10 , Regs );
  134.  
  135.    Color_Screen_Active := ( Regs.Al <> 7 );
  136.  
  137. End    (* Color_Screen_Active *);
  138.  
  139. (*----------------------------------------------------------------------*)
  140. (*     Current_Video_Mode --- Determine current video mode setting      *)
  141. (*----------------------------------------------------------------------*)
  142.  
  143. FUNCTION Current_Video_Mode: INTEGER;
  144.  
  145. (*----------------------------------------------------------------------*)
  146. (*                                                                      *)
  147. (*     Function:   Current_Video_Mode                                   *)
  148. (*                                                                      *)
  149. (*     Purpose:    Gets current video mode setting from system          *)
  150. (*                                                                      *)
  151. (*     Calling Sequence:                                                *)
  152. (*                                                                      *)
  153. (*        Current_Mode := Current_Video_Mode : INTEGER;                 *)
  154. (*                                                                      *)
  155. (*           Current_Mode --- set to integer representing current       *)
  156. (*                            video mode inherited from system.         *)
  157. (*                                                                      *)
  158. (*     Calls:   INTR                                                    *)
  159. (*                                                                      *)
  160. (*----------------------------------------------------------------------*)
  161.  
  162. VAR
  163.    Regs : RegPack;
  164.  
  165. BEGIN  (* Current_Video_Mode *)
  166.  
  167.    Regs.Ax := 15 SHL 8;
  168.  
  169.    INTR( $10 , Regs );
  170.  
  171.    Current_Video_Mode := Regs.Al;
  172.  
  173. End    (* Current_Video_Mode *);
  174.  
  175. (*----------------------------------------------------------------------*)
  176. (*        Get_Screen_Address --- Get address of current screen          *)
  177. (*----------------------------------------------------------------------*)
  178.  
  179. PROCEDURE Get_Screen_Address( VAR Actual_Screen : Screen_Ptr );
  180.  
  181. (*----------------------------------------------------------------------*)
  182. (*                                                                      *)
  183. (*     Procedure:  Get_Screen_Address                                   *)
  184. (*                                                                      *)
  185. (*     Purpose:    Gets screen address for current type of display      *)
  186. (*                                                                      *)
  187. (*     Calling Sequence:                                                *)
  188. (*                                                                      *)
  189. (*        Get_Screen_Address( Var Actual_Screen : Screen_Ptr );         *)
  190. (*                                                                      *)
  191. (*           Actual_Screen --- pointer whose value receives the         *)
  192. (*                             current screen address.                  *)
  193. (*                                                                      *)
  194. (*     Calls:   Color_Screen_Active                                     *)
  195. (*              PTR                                                     *)
  196. (*                                                                      *)
  197. (*----------------------------------------------------------------------*)
  198.  
  199. BEGIN  (* Get_Screen_Address *)
  200.  
  201.    IF Color_Screen_Active THEN
  202.       Actual_Screen := PTR( Color_Screen_Address , 0 )
  203.    ELSE
  204.       Actual_Screen := PTR( Mono_Screen_Address , 0 );
  205.  
  206. END    (* Get_Screen_Address *);
  207.  
  208. (*----------------------------------------------------------------------*)
  209. (*                Video Display Control Routines                        *)
  210. (*----------------------------------------------------------------------*)
  211. (*                                                                      *)
  212. (*       RvsVideoOn  --- Turn On Reverse Video                          *)
  213. (*       RvsVideoOff --- Turn Off Reverse Video                         *)
  214. (*                                                                      *)
  215. (*----------------------------------------------------------------------*)
  216.  
  217. PROCEDURE RvsVideoOn( Foreground_Color, Background_Color : INTEGER );
  218.  
  219. BEGIN (* RvsVideoOn *)
  220.  
  221.    TextColor     ( Background_color );
  222.    TextBackGround( Foreground_color );
  223.  
  224. END   (* RvsVideoOn *);
  225.  
  226. (*----------------------------------------------------------------------*)
  227.  
  228. PROCEDURE RvsVideoOff( Foreground_Color, Background_Color : INTEGER );
  229.  
  230. BEGIN (* RvsVideoOff *)
  231.  
  232.    TextColor     ( Foreground_color );
  233.    TextBackGround( Background_color );
  234.  
  235. END   (* RvsVideoOff *);
  236.  
  237.  
  238. (*----------------------------------------------------------------------*)
  239. (*                TURBO Pascal Window Location Routines                 *)
  240. (*----------------------------------------------------------------------*)
  241. (*                                                                      *)
  242. (*  These routines and constants give the four corners of the current   *)
  243. (*  Turbo window:                                                       *)
  244. (*                                                                      *)
  245. (*    Lower right-hand corner: (Lower_Right_Column, Lower_Right_Row)    *)
  246. (*    Upper left_hand corner:  Upper_Left( Column, Row )                *)
  247. (*                                                                      *)
  248. (*----------------------------------------------------------------------*)
  249.  
  250.                                    (* Lower right corner of     *)
  251.                                    (* current TURBO window      *)
  252. VAR
  253.    Lower_Right_Column  : Byte ABSOLUTE Cseg:$016A;
  254.    Lower_Right_Row     : Byte ABSOLUTE Cseg:$016B;
  255.  
  256. (*----------------------------------------------------------------------*)
  257. (*            Upper_Left ---  Upper Positions of current window         *)
  258. (*----------------------------------------------------------------------*)
  259.  
  260. PROCEDURE Upper_Left( VAR X1, Y1 : INTEGER );
  261.  
  262. (*----------------------------------------------------------------------*)
  263. (*                                                                      *)
  264. (*     Procedure:   Upper_Left                                          *)
  265. (*                                                                      *)
  266. (*     Purpose:    Returns upper positions of current TURBO window      *)
  267. (*                                                                      *)
  268. (*     Calling Sequence:                                                *)
  269. (*                                                                      *)
  270. (*        Upper_Left( VAR X1, Y1 : INTEGER );                           *)
  271. (*                                                                      *)
  272. (*           X1   --- returned upper left column                        *)
  273. (*           Y1   --- returned upper left row                           *)
  274. (*                                                                      *)
  275. (*     Calls:   INTR                                                    *)
  276. (*              WhereX                                                  *)
  277. (*              WhereY                                                  *)
  278. (*              GoToXY                                                  *)
  279. (*                                                                      *)
  280. (*----------------------------------------------------------------------*)
  281.  
  282. VAR
  283.     TempX  : INTEGER;
  284.     TempY  : INTEGER;
  285.     Reg    : RegPack;
  286.  
  287. BEGIN  (* Upper_Left *)
  288.  
  289.     TempX := WhereX;           (* Save Current Cursor Pos. *)
  290.     TempY := WhereY;
  291.  
  292.     GoToXY( 1 , 1 );           (* Goto Upper Left corner of window *)
  293.  
  294.     Reg.Ax := $0300;           (* Set up reg's for INTR *)
  295.     Reg.Bx := 0;
  296.  
  297.     INTR( $10 , Reg );         (* Call BIOS Read Cursor Position *)
  298.  
  299.     Y1 := Reg.Dh + 1;          (* get Row *)
  300.     X1 := Reg.Dl + 1;          (* get Column *)
  301.  
  302.     GoToXY( TempX , TempY );   (* Return to orig. position *)
  303.  
  304. END    (* Upper_Left *);
  305.  
  306.  
  307. (*----------------------------------------------------------------------*)
  308. (*                Set/Reset Text Color Routines                         *)
  309. (*----------------------------------------------------------------------*)
  310. (*                                                                      *)
  311. (*   These routines set and reset the global text foreground and        *)
  312. (*   background colors.                                                 *)
  313. (*                                                                      *)
  314. (*----------------------------------------------------------------------*)
  315.  
  316.                    (* Global Text Color Variables *)
  317.  
  318. VAR
  319.    Global_ForeGround_Color : INTEGER;
  320.    Global_BackGround_Color : INTEGER;
  321.  
  322. (*----------------------------------------------------------------------*)
  323. (*    Set_Global_Colors --- Reset global foreground, background cols.   *)
  324. (*----------------------------------------------------------------------*)
  325.  
  326. PROCEDURE Set_Global_Colors( ForeGround, BackGround : INTEGER );
  327.  
  328. (*----------------------------------------------------------------------*)
  329. (*                                                                      *)
  330. (*     Procedure:  Set_Global_Colors                                    *)
  331. (*                                                                      *)
  332. (*     Purpose:    Sets global text foreground, background colors.      *)
  333. (*                                                                      *)
  334. (*     Calling Sequence:                                                *)
  335. (*                                                                      *)
  336. (*        Set_Global_Colors( ForeGround, BackGround : INTEGER );        *)
  337. (*                                                                      *)
  338. (*           ForeGround --- Default foreground color                    *)
  339. (*           BackGround --- Default background color                    *)
  340. (*                                                                      *)
  341. (*     Calls:   TextColor                                               *)
  342. (*              TextBackGround                                          *)
  343. (*                                                                      *)
  344. (*----------------------------------------------------------------------*)
  345.  
  346. BEGIN  (* Set_Global_Colors *)
  347.  
  348.    Global_ForeGround_Color := ForeGround;
  349.    GLobal_BackGround_Color := BackGround;
  350.  
  351.    TextColor     ( Global_ForeGround_Color );
  352.    TextBackground( Global_BackGround_Color );
  353.  
  354. END    (* Set_Global_Colors *);
  355.  
  356. (*----------------------------------------------------------------------*)
  357. (*  Reset_Global_Colors --- Reset global foreground, background cols.   *)
  358. (*----------------------------------------------------------------------*)
  359.  
  360. PROCEDURE Reset_Global_Colors;
  361.  
  362. (*----------------------------------------------------------------------*)
  363. (*                                                                      *)
  364. (*     Procedure:  Reset_Global_Colors                                  *)
  365. (*                                                                      *)
  366. (*     Purpose:    Resets text foreground, background colors to global  *)
  367. (*                 defaults.                                            *)
  368. (*                                                                      *)
  369. (*     Calling Sequence:                                                *)
  370. (*                                                                      *)
  371. (*        Reset_Global_Colors;                                          *)
  372. (*                                                                      *)
  373. (*     Calls:   TextColor                                               *)
  374. (*              TextBackGround                                          *)
  375. (*                                                                      *)
  376. (*----------------------------------------------------------------------*)
  377.  
  378. BEGIN  (* Reset_Global_Colors *)
  379.  
  380.    TextColor     ( Global_ForeGround_Color );
  381.    TextBackground( Global_BackGround_Color );
  382.  
  383. END    (* Reset_Global_Colors *);
  384.  
  385. (*----------------------------------------------------------------------*)
  386. (*                 Screen Manipulation Routines                         *)
  387. (*----------------------------------------------------------------------*)
  388. (*                                                                      *)
  389. (*   These routines save and restore screen images in support of the    *)
  390. (*   windowing facility.  Also, the current screen image can be printed *)
  391. (*   and text extracted from the screen memory.                         *)
  392. (*                                                                      *)
  393. (*----------------------------------------------------------------------*)
  394.  
  395. (*----------------------------------------------------------------------*)
  396. (*       Get_Screen_Text_Line --- Extract text from screen image        *)
  397. (*----------------------------------------------------------------------*)
  398.  
  399. PROCEDURE Get_Screen_Text_Line( VAR Text_Line     : AnyStr;
  400.                                     Screen_Line   : INTEGER;
  401.                                     Screen_Column : INTEGER );
  402.  
  403. (*----------------------------------------------------------------------*)
  404. (*                                                                      *)
  405. (*     Procedure:  Get_Screen_Text_Line                                 *)
  406. (*                                                                      *)
  407. (*     Purpose:    Extracts text from current screen image              *)
  408. (*                                                                      *)
  409. (*     Calling Sequence:                                                *)
  410. (*                                                                      *)
  411. (*       Get_Screen_Text_Line( Var  Text_Line     : AnyStr;             *)
  412. (*                                  Screen_Line   : INTEGER;            *)
  413. (*                                  Screen_Column : INTEGER );          *)
  414. (*                                                                      *)
  415. (*           Text_Line        --- receives text extracted from screen   *)
  416. (*           Screen_Line      --- line on screen to extract             *)
  417. (*           Screen_Column    --- starting column to extract            *)
  418. (*                                                                      *)
  419. (*     Calls:   None                                                    *)
  420. (*                                                                      *)
  421. (*     Remarks:                                                         *)
  422. (*                                                                      *)
  423. (*        Only the text -- not attributes -- from the screen is         *)
  424. (*        returned.                                                     *)
  425. (*                                                                      *)
  426. (*----------------------------------------------------------------------*)
  427.  
  428. VAR
  429.    First_Pos  : INTEGER;
  430.    Last_Pos   : INTEGER;
  431.    I          : INTEGER;
  432.  
  433. BEGIN  (* Get_Screen_Text_Line *)
  434.  
  435.    Screen_Line   := Max( Min( Screen_Line   , 25 ) , 1 );
  436.    Screen_Column := Max( Min( Screen_Column , 80 ) , 1 );
  437.  
  438.    Text_Line     := '';
  439.    First_Pos     := ( ( Screen_Line - 1 ) * 80 + Screen_Column ) * 2 - 1;
  440.    Last_Pos      := First_Pos + ( 80 - Screen_Column ) * 2 + 1;
  441.  
  442.    REPEAT
  443.       Text_Line := Text_Line + CHR( Actual_Screen^.Screen_Image[ First_Pos ] );
  444.       First_Pos := First_Pos + 2;
  445.    UNTIL ( First_Pos > Last_Pos );
  446.  
  447. END    (* Get_Screen_Text_Line *);
  448.  
  449. (*----------------------------------------------------------------------*)
  450. (*                Print_Screen --- Print current screen image           *)
  451. (*----------------------------------------------------------------------*)
  452.  
  453. PROCEDURE Print_Screen;
  454.  
  455. (*----------------------------------------------------------------------*)
  456. (*                                                                      *)
  457. (*     Procedure:  Print_Screen                                         *)
  458. (*                                                                      *)
  459. (*     Purpose:    Prints current screen image (memory mapped area)     *)
  460. (*                                                                      *)
  461. (*     Calling Sequence:                                                *)
  462. (*                                                                      *)
  463. (*        Print_Screen;                                                 *)
  464. (*                                                                      *)
  465. (*     Calls:   None                                                    *)
  466. (*                                                                      *)
  467. (*     Remarks:                                                         *)
  468. (*                                                                      *)
  469. (*        Only the text from the screen is printed, not the attributes. *)
  470. (*                                                                      *)
  471. (*----------------------------------------------------------------------*)
  472.  
  473. VAR
  474.    I         : INTEGER;
  475.    Text_Line : STRING[80];
  476.  
  477. BEGIN  (* Print_Screen *)
  478.  
  479.    FOR I := 1 TO 25 DO
  480.       BEGIN
  481.          Get_Screen_Text_Line( Text_Line, I, 1 );
  482.          WRITELN( Lst , Text_Line );
  483.       END;
  484.  
  485. END    (* Print_Screen *);
  486.  
  487. (*----------------------------------------------------------------------*)
  488. (*        Write_Screen --- Write current screen image to file           *)
  489. (*----------------------------------------------------------------------*)
  490.  
  491. PROCEDURE Write_Screen( Fname : AnyStr );
  492.  
  493. (*----------------------------------------------------------------------*)
  494. (*                                                                      *)
  495. (*     Procedure:  Write_Screen                                         *)
  496. (*                                                                      *)
  497. (*     Purpose:    Write current screen image (memory mapped area) to   *)
  498. (*                 a file.                                              *)
  499. (*                                                                      *)
  500. (*     Calling Sequence:                                                *)
  501. (*                                                                      *)
  502. (*        Write_Screen( Fname : AnyStr );                               *)
  503. (*                                                                      *)
  504. (*           Fname --- Name of file to write screen to                  *)
  505. (*                                                                      *)
  506. (*     Calls:   None                                                    *)
  507. (*                                                                      *)
  508. (*     Remarks:                                                         *)
  509. (*                                                                      *)
  510. (*        Only the text from the screen is written, not the attributes. *)
  511. (*        If the file already exists, then the new screen is appended   *)
  512. (*        to the end of the file.                                       *)
  513. (*                                                                      *)
  514. (*----------------------------------------------------------------------*)
  515.  
  516. VAR
  517.    I         : INTEGER;
  518.    Text_Line : STRING[80];
  519.    F         : TEXT [512];
  520.  
  521. BEGIN  (* Write_Screen *)
  522.  
  523.       (*$I-*)
  524.    ASSIGN( F , Fname );
  525.    RESET ( F );
  526.  
  527.    IF Int24Result = 0 THEN
  528.       BEGIN
  529.          CLOSE( F );
  530.          APPEND( F );
  531.       END
  532.    ELSE
  533.       BEGIN
  534.          CLOSE  ( F );
  535.          REWRITE( F );
  536.       END;
  537.  
  538.    FOR I := 1 TO 25 DO
  539.       BEGIN
  540.          Get_Screen_Text_Line( Text_Line, I, 1 );
  541.          WRITELN( F , Text_Line );
  542.       END;
  543.  
  544.    CLOSE( F );
  545.      (*$I+*)
  546.  
  547. END    (* Write_Screen *);
  548.  
  549. (*----------------------------------------------------------------------*)
  550. (*                WriteSLin --- Write text string to screen             *)
  551. (*----------------------------------------------------------------------*)
  552.  
  553. PROCEDURE WriteSLin( S: AnyStr; Color: INTEGER );
  554.  
  555. (*----------------------------------------------------------------------*)
  556. (*                                                                      *)
  557. (*     Procedure:  WriteSLin                                            *)
  558. (*                                                                      *)
  559. (*     Purpose:    Writes text string to current line in screen memory  *)
  560. (*                                                                      *)
  561. (*     Calling Sequence:                                                *)
  562. (*                                                                      *)
  563. (*        WriteSLin( S: AnyStr; Color: INTEGER );                       *)
  564. (*                                                                      *)
  565. (*           S      --- String to be written                            *)
  566. (*           Color  --- Color in which to write string                  *)
  567. (*                                                                      *)
  568. (*     Calls:   None                                                    *)
  569. (*                                                                      *)
  570. (*----------------------------------------------------------------------*)
  571.  
  572. VAR
  573.    Length_S : INTEGER;
  574.    S_Column : INTEGER;
  575.    S_Row    : INTEGER;
  576.    I        : INTEGER;
  577.  
  578. BEGIN (* WriteSLin *)
  579.  
  580.    Length_S := LENGTH( S );
  581.  
  582.    S_Column := 1;
  583.    S_Row    := ( WhereY - 1 ) * 160;
  584.  
  585.    FOR I := 1 TO Length_S DO
  586.       WITH Actual_Screen^ DO
  587.          BEGIN
  588.             Screen_Image[ S_Column + S_Row ]     := ORD( COPY( S, I, 1 ) );
  589.             Screen_Image[ S_Column + S_Row + 1 ] := Color;
  590.             S_Column := S_Column + 2;
  591.          END;
  592.  
  593.    S_Row := S_Row + 160;
  594.  
  595.    IF S_Row > 3800 THEN
  596.       InsLine;
  597.  
  598. END   (* WriteSLin *);
  599.  
  600. (*----------------------------------------------------------------------*)
  601. (*          WriteSXY --- Write text string to specified row/column      *)
  602. (*----------------------------------------------------------------------*)
  603.  
  604. PROCEDURE WriteSXY( S: AnyStr; X: INTEGER; Y: INTEGER; Color: INTEGER );
  605.  
  606. (*----------------------------------------------------------------------*)
  607. (*                                                                      *)
  608. (*     Procedure:  WriteSXY                                             *)
  609. (*                                                                      *)
  610. (*     Purpose:    Writes text string at specified row and column       *)
  611. (*                 position on screen.                                  *)
  612. (*                                                                      *)
  613. (*     Calling Sequence:                                                *)
  614. (*                                                                      *)
  615. (*        WriteSXY( S: AnyStr; X: INTEGER; Y: INTEGER; Color: INTEGER );*)
  616. (*                                                                      *)
  617. (*           S      --- String to be written                            *)
  618. (*           X      --- Column position to write string                 *)
  619. (*           Y      --- Column position to write string                 *)
  620. (*           Color  --- Color in which to write string                  *)
  621. (*                                                                      *)
  622. (*     Calls:   None                                                    *)
  623. (*                                                                      *)
  624. (*----------------------------------------------------------------------*)
  625.  
  626. VAR
  627.    Length_S : INTEGER;
  628.    S_Column : INTEGER;
  629.    S_Row    : INTEGER;
  630.    I        : INTEGER;
  631.    S_Pos    : INTEGER;
  632.  
  633. BEGIN (* WriteSXY *)
  634.  
  635.    Length_S := LENGTH( S );
  636.    S_Pos    := 0;
  637.  
  638.    FOR I := 1 TO Length_S DO
  639.       WITH Actual_Screen^ DO
  640.          IF S_Pos < 4001 THEN
  641.             BEGIN
  642.                S_Pos                     := ( ( Y - 1 ) * 80 + X ) * 2 - 1;
  643.                Screen_Image[ S_Pos     ] := ORD( COPY( S, I, 1 ) );
  644.                Screen_Image[ S_Pos + 1 ] := Color;
  645.                X                         := X + 1;
  646.             END;
  647.  
  648. END   (* WriteSXY *);
  649.  
  650. (*----------------------------------------------------------------------*)
  651. (*   WriteCXY --- Write character to screen  at specified row/column    *)
  652. (*----------------------------------------------------------------------*)
  653.  
  654. PROCEDURE WriteCXY( C: CHAR; X: INTEGER; Y: INTEGER; Color: INTEGER );
  655.  
  656. (*----------------------------------------------------------------------*)
  657. (*                                                                      *)
  658. (*     Procedure:  WriteCXY                                             *)
  659. (*                                                                      *)
  660. (*     Purpose:    Writes a character at specified row and column       *)
  661. (*                 position on screen.                                  *)
  662. (*                                                                      *)
  663. (*     Calling Sequence:                                                *)
  664. (*                                                                      *)
  665. (*        WriteCXY( C: CHAR; X: INTEGER; Y: INTEGER; Color: INTEGER );  *)
  666. (*                                                                      *)
  667. (*           C      --- Character to be written                         *)
  668. (*           X      --- Column position to write string                 *)
  669. (*           Y      --- Column position to write string                 *)
  670. (*           Color  --- Color in which to write string                  *)
  671. (*                                                                      *)
  672. (*     Calls:   None                                                    *)
  673. (*                                                                      *)
  674. (*----------------------------------------------------------------------*)
  675.  
  676. VAR
  677.    S_Pos : INTEGER;
  678.  
  679. BEGIN (* WriteCXY *)
  680.  
  681.    WITH Actual_Screen^ DO
  682.       BEGIN
  683.          S_Pos                     := ( ( Y - 1 ) * 80 + X ) * 2 - 1;
  684.          Screen_Image[ S_Pos     ] := ORD( C );
  685.          Screen_Image[ S_Pos + 1 ] := Color;
  686.       END;
  687.  
  688. END   (* WriteCXY *);
  689.  
  690. (*----------------------------------------------------------------------*)
  691. (*                Save_Screen --- Save current screen image             *)
  692. (*----------------------------------------------------------------------*)
  693.  
  694. PROCEDURE Save_Screen( VAR Saved_Screen_Pointer : Saved_Screen_Ptr );
  695.  
  696. (*----------------------------------------------------------------------*)
  697. (*                                                                      *)
  698. (*     Procedure:  Save_Screen                                          *)
  699. (*                                                                      *)
  700. (*     Purpose:    Saves current screen image (memory mapped area)      *)
  701. (*                                                                      *)
  702. (*     Calling Sequence:                                                *)
  703. (*                                                                      *)
  704. (*        Save_Screen( Var Saved_Screen_Pointer : Saved_Screen_Ptr );   *)
  705. (*                                                                      *)
  706. (*           Saved_Screen_Pointer  --- pointer to record receiving      *)
  707. (*                                     screen image, window location,   *)
  708. (*                                     and current cursor location.     *)
  709. (*                                                                      *)
  710. (*     Calls:   Move                                                    *)
  711. (*              Upper_Left                                              *)
  712. (*                                                                      *)
  713. (*     Remarks:                                                         *)
  714. (*                                                                      *)
  715. (*        This version checks for stack overflow.                       *)
  716. (*                                                                      *)
  717. (*----------------------------------------------------------------------*)
  718.  
  719. BEGIN  (* Save_Screen *)
  720.                                    (* Overwrite last screen if no room *)
  721.  
  722.    IF Current_Saved_Screen >= Max_Saved_Screen THEN
  723.       Saved_Screen_Pointer := Saved_Screen_List[ Max_Saved_Screen ]
  724.    ELSE
  725.       BEGIN
  726.          Current_Saved_Screen := Current_Saved_Screen + 1;
  727.          NEW( Saved_Screen_Pointer );
  728.          Saved_Screen_List[ Current_Saved_Screen ] := Saved_Screen_Pointer;
  729.       END;
  730.  
  731.    WITH Saved_Screen_Pointer^ DO
  732.       BEGIN
  733.  
  734.          Upper_Left( Screen_X1, Screen_Y1 );
  735.  
  736.          Screen_X2     := Lower_Right_Column;
  737.          Screen_Y2     := Lower_Right_Row;
  738.  
  739.          Screen_Row    := WhereY;
  740.          Screen_Column := WhereX;
  741.  
  742.          MOVE( Actual_Screen^.Screen_Image, Screen_Image, Screen_Length );
  743.  
  744.       END;
  745.  
  746. END   (* Save_Screen *);
  747.  
  748. (*----------------------------------------------------------------------*)
  749. (*              Restore_Screen --- Restore saved screen image           *)
  750. (*----------------------------------------------------------------------*)
  751.  
  752. PROCEDURE Restore_Screen( VAR Saved_Screen_Pointer : Saved_Screen_Ptr );
  753.  
  754. (*----------------------------------------------------------------------*)
  755. (*                                                                      *)
  756. (*     Procedure:  Restore_Screen                                       *)
  757. (*                                                                      *)
  758. (*     Purpose:    Restores previously saved screen image.              *)
  759. (*                                                                      *)
  760. (*     Calling Sequence:                                                *)
  761. (*                                                                      *)
  762. (*        Restore_Screen( Var Saved_Screen_Pointer: Saved_Screen_Ptr ); *)
  763. (*                                                                      *)
  764. (*           Saved_Screen_Pointer  --- pointer to record with saved     *)
  765. (*                                     screen image, window location,   *)
  766. (*                                     and cursor location.             *)
  767. (*                                                                      *)
  768. (*     Calls:   Window                                                  *)
  769. (*              Move                                                    *)
  770. (*              GoToXY                                                  *)
  771. (*                                                                      *)
  772. (*     Remarks:                                                         *)
  773. (*                                                                      *)
  774. (*        All saved screen pointers from the last saved down to the     *)
  775. (*        argument pointer are popped from the saved screen list.       *)
  776. (*                                                                      *)
  777. (*----------------------------------------------------------------------*)
  778.  
  779. BEGIN  (* Restore_Screen *)
  780.  
  781.    WITH Saved_Screen_Pointer^ DO
  782.       BEGIN
  783.  
  784.          Window( Screen_X1, Screen_Y1, Screen_X2, Screen_Y2 );
  785.  
  786.          MOVE( Screen_Image, Actual_Screen^.Screen_Image, Screen_Length );
  787.  
  788.          GoToXY( Screen_Column, Screen_Row );
  789.  
  790.       END;
  791.  
  792.    WHILE( Saved_Screen_List[ Current_Saved_Screen ] <> Saved_Screen_Pointer ) DO
  793.       BEGIN
  794.          DISPOSE( Saved_Screen_List[ Current_Saved_Screen ] );
  795.          Current_Saved_Screen := Current_Saved_Screen - 1;
  796.       END;
  797.  
  798.    IF Current_Saved_Screen > 0 THEN
  799.       Current_Saved_Screen := Current_Saved_Screen - 1;
  800.  
  801.    DISPOSE( Saved_Screen_Pointer );
  802.  
  803.    Saved_Screen_Pointer := NIL;
  804.  
  805. END    (* Restore_Screen *);
  806.